package com.pureut.production.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pureut.common.core.exception.GlobalException;
import com.pureut.common.core.web.domain.AjaxResult;
import com.pureut.common.datascope.annotation.DataScope;
import com.pureut.common.security.utils.DictUtils;
import com.pureut.common.security.utils.SecurityUtils;
import com.pureut.production.domain.*;
import com.pureut.production.domain.dto.*;
import com.pureut.production.domain.vo.*;
import com.pureut.production.mapper.*;
import com.pureut.production.service.*;
import com.pureut.system.api.FeignService;
import com.pureut.system.api.QualityFeginService;
import com.pureut.system.api.SchedulingPlanFeignService;
import com.pureut.system.api.StorageFegin;
import com.pureut.system.api.domain.SysDictData;
import com.pureut.system.api.vo.BackWeight;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/***
 * 分切制令单实现层
 * Author:C
 * Date:2023/02/16 10:16
 * @DESC
 */
@Service
public class CutOrdersDocumentServiceImpl extends ServiceImpl<CutOrdersDocumentMapper, CutOrdersDocument> implements CutOrdersDocumentService {


    @Resource
    CutOrdersDocumentMapper cutOrdersDocumentMapper;

    @Resource
    CutOrdersDocumentDetailMapper cutOrdersDocumentDetailMapper;

    @Resource
    CutOrdersDocumentDetailService cutOrdersDocumentDetailService;

    @Lazy
    @Resource
    RollPackingService rollPackingService;

    @Lazy
    @Resource
    RollPackingMapper rollPackingMapper;

    @Resource
    FeignService feignService;

    @Resource
    QualityFeginService qualityFeginService;

    @Resource
    StorageFegin storageFegin;

    @Resource
    @Lazy
    SpunlaceOrderMapper spunlaceOrderMapper;

    @Resource
    IWasteTubeService wasteTubeService;

    @Resource
    SchedulingPlanFeignService schedulingPlanFeignService;

    @Resource
    SysShopModelingService sysShopModelingService;

    @Resource
    DegreasDocumentMapper degreasDocumentMapper;

    @Resource
    WeighingFinishedMaterialProductMapper weighingFinishedMaterialProductMapper;

    /**
     * 分切制令单列表
     */
    @Override
    @DataScope(deptAlias = "a")
    public List<CutOrdersDocumentDto> getList(CutOrdersDocumentVo cutOrdersDocumentVo) {
        //生产状态
        List<SysDictData> orderStatusArray = DictUtils.getDictCache("splitting_order_number_status");
        Map<String, String> orderStatusMap = orderStatusArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //包装要求
        List<SysDictData> packingArray = DictUtils.getDictCache("sale_order_packing");
        Map<String, String> packingMap = packingArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //纸管小卷数
        List<SysDictData> rollsArray = DictUtils.getDictCache("sale_order_number_rolls");
        Map<String, String> rollsMap = rollsArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //单位
        List<SysDictData> unitArray = DictUtils.getDictCache("sys_material_unit");
        Map<String, String> unitMap = unitArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        List<CutOrdersDocumentDto> list = cutOrdersDocumentMapper.getList(cutOrdersDocumentVo);

        for (CutOrdersDocumentDto entity : list) {
            //生产状态
            entity.setProductStatusDict(orderStatusMap.get(entity.getProductStatus()));
            //包装要求
            entity.setPackingRequirementDict(packingMap.get(entity.getPackingRequirement()));
            List<String> strings = Arrays.asList(entity.getSmallRollNum().split(","));
            StringBuilder stringBuilder = new StringBuilder();
            for (String entity1 : strings) {
                stringBuilder.append(rollsMap.get(entity1)).append(",");
            }
            StringBuilder stringBuilder1 = stringBuilder.deleteCharAt(stringBuilder.length() - 1);
            //纸管小卷数
            entity.setSmallRollNumDict(stringBuilder1.toString());
            //单位
            entity.setMaterialUnitDict(unitMap.get(entity.getMaterialUnit()));
        }
        return list;
    }

    /**
     * 新增
     *
     * @param cutOrdersDocumentVo
     * @return
     */
    @Override
    public boolean add(CutOrdersDocumentVo cutOrdersDocumentVo) throws Exception {

        CutOrdersDocument cutOrdersDocument = new CutOrdersDocument();

        cutOrdersDocument
                //.setSplittingOrderNumber(feignService.splitList("FQ"))
                .setSplittingOrderNumber(cutOrdersDocumentVo.getSplittingOrderNumber())
                .setWhetherExemption(2)
                .setProductStatus(2)
                .setMaterialCode(cutOrdersDocumentVo.getMaterialCode())
                .setWidth(cutOrdersDocumentVo.getWidth())
                .setSmallRollNum(cutOrdersDocumentVo.getSmallRollNum())
                .setMasterRollNum(cutOrdersDocumentVo.getMasterRollNum())
                .setPlanWeight(cutOrdersDocumentVo.getPlanWeight())
                .setPackingRequirement(cutOrdersDocumentVo.getPackingRequirement())
                .setWorkshopId(cutOrdersDocumentVo.getWorkshopId())
                .setProductionPlanSheet(cutOrdersDocumentVo.getProductionPlanSheet())
                .setCreateBy(SecurityUtils.getUsername())
                .setCreateTime(new Date())
                .setDeptId(SecurityUtils.getDeptId())
                .setOrderRemark(cutOrdersDocumentVo.getOrderRemark())
                .setPlanRemark(cutOrdersDocumentVo.getPlanRemark())
                .setSchedulRemark(cutOrdersDocumentVo.getSchedulRemark())
                .setCustomerCode(cutOrdersDocumentVo.getCustomerCode())
                .setWindingDiameter(cutOrdersDocumentVo.getWindingDiameter())
                .setLineTypeName(cutOrdersDocumentVo.getLineTypeName())
                .setPackSmallRolls(cutOrdersDocumentVo.getPackSmallRolls())
                .setSaleNumber(cutOrdersDocumentVo.getSaleNumber());
        return save(cutOrdersDocument);
    }


    /**
     * 是否免检修改（1：开，2：关）
     *
     * @param switchVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean getSwitch(SwitchVo switchVo) {
        CutOrdersDocument cutOrdersDocument = getById(switchVo.getId());
        cutOrdersDocument.setWhetherExemption(switchVo.getSwitchValue());
        return updateById(cutOrdersDocument);
//        if (b) {
//            //将明细中的数据状态都改为免检
//            List<CutOrdersDocumentDetail> cutOrdersDocumentDetailList = cutOrdersDocumentDetailMapper.selectList(new QueryWrapper<CutOrdersDocumentDetail>().lambda().eq(CutOrdersDocumentDetail::getDocumentNum, cutOrdersDocument.getSplittingOrderNumber()));
//            for (CutOrdersDocumentDetail entity : cutOrdersDocumentDetailList) {
//                entity.setClothInspectionStatus(2);
//            }
//            cutOrdersDocumentDetailService.updateBatchById(cutOrdersDocumentDetailList);
//        }
//        return b;
    }

    /**
     * 查看
     *
     * @param id
     * @return
     */
    @Override
    public CutOrdersDocumentDto getViewById(Long id) {
        //包装要求
        List<SysDictData> packingArray = DictUtils.getDictCache("sale_order_packing");
        Map<String, String> packingMap = packingArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //纸管小卷数
        List<SysDictData> rollsArray = DictUtils.getDictCache("sale_order_number_rolls");
        Map<String, String> rollsMap = rollsArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        CutOrdersDocumentDto viewById = cutOrdersDocumentMapper.getViewById(id);

        viewById.setPackingRequirementDict(packingMap.get(viewById.getPackingRequirement()));

        List<String> strings = Arrays.asList(viewById.getSmallRollNum().split(","));
        StringBuilder stringBuilder = new StringBuilder();
        for (String entity1 : strings) {
            stringBuilder.append(rollsMap.get(entity1)).append(",");
        }
        StringBuilder stringBuilder1 = stringBuilder.deleteCharAt(stringBuilder.length() - 1);
        viewById.setSmallRollNumDict(stringBuilder1.toString());

        return viewById;
    }

    /**
     * 上线
     *
     * @param cutOrdersDocumentVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean goOnline(CutOrdersDocumentVo cutOrdersDocumentVo) {


        //判断每包小卷数格式是否正确
        String packSmallRolls = cutOrdersDocumentVo.getPackSmallRolls();
        boolean matches = packSmallRolls.matches("^[1-9]+(,[1-9]+)*$");
        if (!matches) {
            throw new GlobalException("每包小卷数只能为正整数，并用英文逗号隔开");
        }
        //校验同一线别下只允许有一条“生产中”的制令单
        String lineTypeName = cutOrdersDocumentVo.getLineTypeName();
        List<String> lineCodes = Arrays.asList(lineTypeName.split(","));

        List<CutOrdersDocumentDto> cutOrdersDocumentDto = cutOrdersDocumentMapper.selectLike(lineCodes);
        if (cutOrdersDocumentDto.size() > 0) {
            throw new GlobalException("同一线别下只允许有一条“生产中”的制令单");

        }

        CutOrdersDocument cutOrdersDocument = getById(cutOrdersDocumentVo.getId());
        if (cutOrdersDocument.getProductStatus() == 2 || cutOrdersDocument.getProductStatus() == 3) {
            cutOrdersDocument.setLineTypeName(cutOrdersDocumentVo.getLineTypeName())
                    .setPackSmallRolls(cutOrdersDocumentVo.getPackSmallRolls())
                    .setCutRemark(cutOrdersDocumentVo.getCutRemark())
                    .setRollLabel(cutOrdersDocumentVo.getRollLabel())
                    .setFinishedLabel(cutOrdersDocumentVo.getFinishedLabel())
                    .setProductStatus(1);
        } else {
            throw new GlobalException("只能操作“待上线”和“暂停”状态的单据");
        }
        return updateById(cutOrdersDocument);
    }


    /**
     * 分切完成
     *
     * @param slittingCompletionVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public SlittingCompletionDto slittingCompletion(SlittingCompletionVo slittingCompletionVo) throws Exception {

        SlittingCompletionDto slittingCompletionDto = new SlittingCompletionDto();

        CutOrdersDocument cutOrdersDocument = getById(slittingCompletionVo.getId());
        if (cutOrdersDocument.getProductStatus() != 1) {
            slittingCompletionDto.setResultCode("500");
            slittingCompletionDto.setResultMessage("单据状态不为生产中，对应的明细不能进行分切操作");
            return slittingCompletionDto;
        }
        //获取明细数据
        CutOrdersDocumentDetailDto detailByDocumentNum = cutOrdersDocumentDetailMapper.getDetailByDocumentNum(slittingCompletionVo.getInputValue());
        if (detailByDocumentNum == null) {
            slittingCompletionDto.setResultCode("500");
            slittingCompletionDto.setResultMessage("不存在该明细，请核实!");
            return slittingCompletionDto;
        }
        //判断是否验布完成
        if (!("4".equals(detailByDocumentNum.getClothInspectionStatus())) && !("2".equals(detailByDocumentNum.getClothInspectionStatus()))) {
            slittingCompletionDto.setResultCode("500");
            slittingCompletionDto.setResultMessage("请先进行验布操作");
            return slittingCompletionDto;
        }
        //判断是否进行分切过
        if ("2".equals(detailByDocumentNum.getSlittingStatus())) {
            slittingCompletionDto.setResultMessage("已存在该明细分切数据");
            slittingCompletionDto.setResultCode("500");
            return slittingCompletionDto;
        }
        //获取制令单中幅宽的分切数量
        List<String> withList = Arrays.asList(cutOrdersDocument.getWidth().split(","));

        //获取跨天时间和班次
        AjaxResult ajaxResult = schedulingPlanFeignService.selectShiftLine(cutOrdersDocument.getLineTypeName());
        List<CalendarTeamDto> data = JSON.parseArray(JSON.toJSONString(ajaxResult.get("data")), CalendarTeamDto.class);

        if (data==null){
            throw new GlobalException("请先配置工厂日历");
        }

        Date crossSkyTime = null;
        String classDifference = null;
        for (CalendarTeamDto entity : data) {

            Date nowTime = new Date();
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(nowTime);
            Date time = calendar.getTime();
            //判断当前时间是否在开始时间和结束时间之内
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
            String time2 = simpleDateFormat.format(time);
            String time3 = entity.getTeamStartTime();
            String time4 = entity.getTeamEndTime();
            if (time2.compareTo(time3) > 0 && time2.compareTo(time4) < 0) {
                //获取班组
                classDifference = entity.getTeamInfo();
                //判断是否跨天,并判断当前时间小于开始时间
                if (entity.getTeamTranssky() == 1 && time2.compareTo(time3) < 0) {
                    //如果跨天就取前一天
                    Date date = new Date();
                    //得到日历
                    Calendar calendar1 = Calendar.getInstance();
                    //把当前时间赋给日历
                    calendar1.setTime(date);
                    //设置为前一天
                    calendar1.add(Calendar.DAY_OF_MONTH, -1);
                    //得到前一天的时间
                    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
                    String format = sf.format(calendar1.getTime());
                    //得到前一天的时间
                    crossSkyTime = new SimpleDateFormat("yyyy-MM-dd").parse(format);
                } else {
                    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
                    String format = sf.format(new Date());
                    //得到前一天的时间
                    crossSkyTime = new SimpleDateFormat("yyyy-MM-dd").parse(format);
                }
            }
        }
        if (crossSkyTime == null && classDifference == null) {
            slittingCompletionDto.setResultCode("500");
            slittingCompletionDto.setResultMessage("未进行工厂日历配置");
            return slittingCompletionDto;
        }

        //获取计划单号
        String[] productionPlanSheetList = cutOrdersDocument.getProductionPlanSheet().split(",");
        String[] split = cutOrdersDocument.getWidth().split(",");

        List<RollPacking> rollPackingList = new ArrayList<>();
        for (int j = 0; j < productionPlanSheetList.length; j++) {
            //获取幅宽
            String with = split[j].substring(0, split[j].indexOf("*"));
            //截取*之后字符串
            String str1 = split[j].substring(0, split[j].indexOf("*"));
            //获取分切数量
            int slittNum = Integer.parseInt(split[j].substring(str1.length() + 1));
            //生成小卷打包数据
            for (int i = 1; i <= slittNum; i++) {
                RollPacking rollPacking = new RollPacking();
                rollPacking.setLineType(String.valueOf(cutOrdersDocument.getLineTypeName()))
                        .setSmallVolumeNumber("FQ" + feignService.splitList("XJHM"))
                        .setWidth(with)
                        .setRollLength(detailByDocumentNum.getRollLength())
                        .setJoint(detailByDocumentNum.getJoint())
                        .setPrintStatus(1)
                        .setMasterVolumeNumber(detailByDocumentNum.getMasterVolumeNum())
                        .setPlanNumber(productionPlanSheetList[j])
                        .setSplittingOrderNumber(detailByDocumentNum.getDocumentNum())
                        .setMaterialCode(detailByDocumentNum.getMaterialCode())
                        .setFeeder(SecurityUtils.getUsername())
                        .setSplittingTime(new Date())
                        .setCreateTime(new Date())
                        .setDeptId(SecurityUtils.getDeptId())
                        .setCrossSkyTime(crossSkyTime)
                        .setClassDifference(classDifference);
                rollPackingList.add(rollPacking);
            }
        }

        //保存小卷打包数据
        boolean b = rollPackingService.saveBatch(rollPackingList);

        //修改制令单已分切数量
        //cutOrdersDocument.setCutNum(rollPackingList.size());
        cutOrdersDocument.setCutNum(cutOrdersDocument.getCutNum() + 1);
        updateById(cutOrdersDocument);

        CutOrdersDocumentDetail cutOrdersDocumentDetail = cutOrdersDocumentDetailService.getById(detailByDocumentNum.getId());
        //封装返回数据
        slittingCompletionDto.setMaterialCode(cutOrdersDocumentDetail.getMaterialCode());
        slittingCompletionDto.setMaterialName(detailByDocumentNum.getMaterialName());
        slittingCompletionDto.setProductNumber(cutOrdersDocumentDetail.getProductNumber());
        if (b) {
            //修改该明细状态为分切完成
            cutOrdersDocumentDetail.setSlittingStatus(2);
            cutOrdersDocumentDetail.setSlittTime(new Date());
            cutOrdersDocumentDetail.setSlittBy(SecurityUtils.getUsername());
            cutOrdersDocumentDetailService.updateById(cutOrdersDocumentDetail);
            //删除仓库中对应的物料
            String masterVolumeNum = cutOrdersDocumentDetail.getMasterVolumeNum();
            storageFegin.deleteByMasterVolumeNum(masterVolumeNum);
            slittingCompletionDto.setResultCode("200");
            slittingCompletionDto.setResultMessage("分切成功！");
            slittingCompletionDto.setResultMessage("物料号码:" + detailByDocumentNum.getMasterVolumeNum() + "," + "物料名称:" + detailByDocumentNum.getMaterialName() + "," + "分切成功");
            return slittingCompletionDto;
        } else {
            slittingCompletionDto.setResultCode("500");
            slittingCompletionDto.setResultMessage("物料号码:" + detailByDocumentNum.getMasterVolumeNum() + "," + "物料名称:" + detailByDocumentNum.getMaterialName() + "," + "分切失败");
            return slittingCompletionDto;
        }
    }

    /**
     * 分卷
     *
     * @param subVolumeVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public SubVolumePdaDto subVolume(SubVolumeVo subVolumeVo) throws Exception {
        SubVolumePdaDto subVolumePdaDto = new SubVolumePdaDto();
        //根据产品号码获取明细
        List<CutOrdersDocumentDetailDto> list = cutOrdersDocumentDetailMapper.getViewByProductNumber(subVolumeVo.getProductNumber());

        CutOrdersDocumentDetailDto cutOrdersDocumentDetail = list.get(0);
        //根据关联字段获取制令单
        CutOrdersDocument cutOrdersDocument = cutOrdersDocumentMapper.selectOne(new QueryWrapper<CutOrdersDocument>().lambda().eq(CutOrdersDocument::getSplittingOrderNumber, cutOrdersDocumentDetail.getDocumentNum()));
        if (cutOrdersDocument == null) {
            subVolumePdaDto.setCode("500");
            subVolumePdaDto.setMessage("该母卷号码不属于当前单据");
            return subVolumePdaDto;
        }
        //校验是否免检
        if (cutOrdersDocument.getWhetherExemption() == 2) {
            if (!("4".equals(cutOrdersDocumentDetail.getClothInspectionStatus()))) {
                subVolumePdaDto.setCode("500");
                subVolumePdaDto.setMessage("请先进行验布操作");
                return subVolumePdaDto;
            }
        }
        //校验是否分卷过
        if ("2".equals(cutOrdersDocumentDetail.getSlittingStatus())) {
            subVolumePdaDto.setCode("500");
            subVolumePdaDto.setMessage("该母卷已经分卷过");
            return subVolumePdaDto;
        }
        //获取分卷数量
        int subVolumeNum = subVolumeVo.getSubVolumeNum();
        //分卷之后的数据
        //幅宽
        BigDecimal divideWidth = new BigDecimal(cutOrdersDocumentDetail.getWidth()).divide(new BigDecimal(subVolumeNum), 0);
        //卷长
        BigDecimal divideRollLength = new BigDecimal(cutOrdersDocumentDetail.getRollLength()).divide(new BigDecimal(subVolumeNum), 0);
        //克重
        BigDecimal divideGramWeight = new BigDecimal(cutOrdersDocumentDetail.getGramWeight()).divide(new BigDecimal(subVolumeNum), 0);
        //卷径
        BigDecimal divideRollDiameter = new BigDecimal(cutOrdersDocumentDetail.getRollDiameter()).divide(new BigDecimal(subVolumeNum), 0);

        List<RollPacking> rollList = new ArrayList<>();

        //获取跨天时间和班次
        AjaxResult ajaxResult = schedulingPlanFeignService.selectShiftLine(subVolumeVo.getLineType());
        List<CalendarTeamDto> data = JSON.parseArray(JSON.toJSONString(ajaxResult.get("data")), CalendarTeamDto.class);

        Date crossSkyTime = null;
        String classDifference = null;
        for (CalendarTeamDto entity : data) {

            Date nowTime = new Date();
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(nowTime);
            Date time = calendar.getTime();
            //判断当前时间是否在开始时间和结束时间之内
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
            String time2 = simpleDateFormat.format(time);
            String time3 = entity.getTeamStartTime();
            String time4 = entity.getTeamEndTime();
            if (time2.compareTo(time3) > 0 && time2.compareTo(time4) < 0) {
                //获取班组
                classDifference = entity.getTeamInfo();
                //判断是否跨天,并判断当前时间小于开始时间
                if (entity.getTeamTranssky() == 1 && time2.compareTo(time3) < 0) {
                    //如果跨天就取前一天
                    Date date = new Date();
                    //得到日历
                    Calendar calendar1 = Calendar.getInstance();
                    //把当前时间赋给日历
                    calendar1.setTime(date);
                    //设置为前一天
                    calendar1.add(Calendar.DAY_OF_MONTH, -1);
                    //得到前一天的时间
                    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
                    String format = sf.format(calendar1.getTime());
                    //得到前一天的时间
                    crossSkyTime = new SimpleDateFormat("yyyy-MM-dd").parse(format);
                } else {
                    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
                    String format = sf.format(new Date());
                    //得到前一天的时间
                    crossSkyTime = new SimpleDateFormat("yyyy-MM-dd").parse(format);
                }
            }
        }
        if (crossSkyTime == null && classDifference == null) {
            subVolumePdaDto.setCode("500");
            subVolumePdaDto.setMessage("未进行工厂日历配置");
            return subVolumePdaDto;
        }

        for (int i = 1; i <= subVolumeNum; i++) {
            RollPacking rollPacking = new RollPacking();
            rollPacking.setLineType(String.valueOf(subVolumeVo.getLineType()))
//                    .setSmallVolumeNumber("FJ" + feignService.splitList("FJ"))
                    .setWidth(divideWidth.toString())
                    .setRollLength(divideRollLength.toString())
                    .setJoint(cutOrdersDocumentDetail.getJoint())
                    .setPrintStatus(1)
                    .setMasterVolumeNumber(cutOrdersDocumentDetail.getMasterVolumeNum())
                    .setPlanNumber(cutOrdersDocument.getProductionPlanSheet())
                    .setSplittingOrderNumber(cutOrdersDocumentDetail.getDocumentNum())
                    .setMaterialCode(cutOrdersDocumentDetail.getMaterialCode())
                    .setClassDifference(classDifference)
                    .setCrossSkyTime(crossSkyTime)
                    .setFeeder(SecurityUtils.getUsername())
                    .setSplittingTime(new Date())
                    .setCreateTime(new Date())
                    .setDeptId(SecurityUtils.getDeptId());
            rollList.add(rollPacking);
        }

        //再将每一卷进行分切

        //获取制令单中幅宽的分切数量
        List<String> withList = Arrays.asList(cutOrdersDocument.getWidth().split(","));
        List<RollPacking> rollPackingList = new ArrayList<>();

        //获取计划单号
        String[] productionPlanSheetList = cutOrdersDocument.getProductionPlanSheet().split(",");
        String[] split = cutOrdersDocument.getWidth().split(",");
        for (RollPacking entity : rollList) {
//            List<RollPacking> rollPackingList = new ArrayList<>();
            for (int j = 0; j < productionPlanSheetList.length; j++) {
                //获取幅宽
                String with = split[j].substring(0, split[j].indexOf("*"));
                //截取*之后字符串
                String str1 = split[j].substring(0, split[j].indexOf("*"));
                //获取分切数量
                int slittNum = Integer.parseInt(split[j].substring(str1.length() + 1));
                //生成小卷打包数据
                for (int i = 1; i <= slittNum; i++) {
                    RollPacking rollPacking = new RollPacking();
                    rollPacking.setLineType(String.valueOf(cutOrdersDocument.getLineTypeName()))
//                            .setSmallVolumeNumber("FQ" + feignService.splitList("XJHM"))
                            .setSmallVolumeNumber("FQ" + feignService.splitList("XJHM"))
                            .setWidth(with)
                            .setRollLength(entity.getRollLength())
                            .setJoint(entity.getJoint())
                            .setPrintStatus(1)
                            .setMasterVolumeNumber(entity.getMasterVolumeNumber())
                            .setPlanNumber(productionPlanSheetList[j])
                            .setSplittingOrderNumber(cutOrdersDocument.getSplittingOrderNumber())
                            .setMaterialCode(entity.getMaterialCode())
                            .setFeeder(SecurityUtils.getUsername())
                            .setSplittingTime(new Date())
                            .setCreateTime(new Date())
                            .setDeptId(SecurityUtils.getDeptId())
                            .setCrossSkyTime(crossSkyTime)
                            .setClassDifference(classDifference);
                    rollPackingList.add(rollPacking);
                }
            }
        }
        rollPackingService.saveBatch(rollPackingList);
        //将分切次数加1
        cutOrdersDocument.setCutNum(cutOrdersDocument.getCutNum() + 1);
        updateById(cutOrdersDocument);
        //修改之前的明细状态
        CutOrdersDocumentDetail byId = cutOrdersDocumentDetailService.getById(cutOrdersDocumentDetail.getId());
        byId.setSlittingStatus(2);
        byId.setSlittTime(new Date());
        byId.setSlittBy(SecurityUtils.getUsername());
        cutOrdersDocumentDetailService.updateById(byId);
        //保存小卷打包数据
        subVolumePdaDto.setMessage("操作成功");
        subVolumePdaDto.setCode("200");
        return subVolumePdaDto;
    }

    /**
     * 停产
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean stopProduction(Long id) {
        CutOrdersDocument cutOrdersDocument = getById(id);
        if (cutOrdersDocument.getProductStatus() == 1) {
            //清空线别
            cutOrdersDocument.setLineTypeName("");
            cutOrdersDocument.setProductStatus(3);
            return updateById(cutOrdersDocument);
        } else {
            throw new GlobalException("仅“生产中”制令单可以进行停产");
        }
    }

    /**
     * 单据完成
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean completionDocuments(Long id) {

        CutOrdersDocument cutOrdersDocument = getById(id);
        //只有“生产中”的制令单可以操作单据完成
        if (cutOrdersDocument.getProductStatus() != 1) {
            throw new GlobalException("只可以操作“生产中”的制令单");
        }
        //必须产出重量>=计划重量才可以进行单据完成
        long outputWeight = Double.doubleToLongBits(cutOrdersDocument.getOutputWeight());
        long planWeight = Double.doubleToLongBits(cutOrdersDocument.getPlanWeight());
        if (outputWeight < planWeight) {
            throw new GlobalException("必须产出重量>=计划重量才可以进行单据完成");
        }
        //校验制令单内是否存在“未分切”的产品号码，如存在不允许单据完成，提醒：存在未分切母卷
        boolean isTrue = true;
        List<CutOrdersDocumentDetail> cutOrdersDocumentDetailList = cutOrdersDocumentDetailMapper.selectList(new QueryWrapper<CutOrdersDocumentDetail>().lambda().eq(CutOrdersDocumentDetail::getDocumentNum, cutOrdersDocument.getSplittingOrderNumber()));
        for (CutOrdersDocumentDetail entityDetail : cutOrdersDocumentDetailList) {
            if (entityDetail.getSlittingStatus() == 1) {
                isTrue = false;
                break;
            }
        }
        //操作时校验小卷打包页面是否存在此分切执行单的小卷，是则提示“存在小卷未打包，请打包后再操作”，否则操作成功
        List<RollPacking> rollPackings = rollPackingMapper.selectList(new QueryWrapper<RollPacking>().lambda().eq(RollPacking::getSplittingOrderNumber, cutOrdersDocument.getSplittingOrderNumber()));
        if (rollPackings.size() > 0) {
            throw new GlobalException("存在小卷未打包，请打包后再操作");
        }
        //操作时校验成品称重页面是否存在此分切执行单的成品未入库，是则提示“存在小卷未打包，请打包后再操作”，否则操作成功
        List<WeighingFinishedMaterialProduct> weighingFinishedMaterialProducts = weighingFinishedMaterialProductMapper.selectList(new QueryWrapper<WeighingFinishedMaterialProduct>().lambda().eq(WeighingFinishedMaterialProduct::getSplittingOrderNumber, cutOrdersDocument.getSplittingOrderNumber()));
        boolean isWeightAll = true;
        for (WeighingFinishedMaterialProduct entity : weighingFinishedMaterialProducts) {
            if (entity.getStorageStatus() == 1) {
                isWeightAll = false;
                break;
            }
        }
        if (!isWeightAll) {
            throw new GlobalException("存在未入库数据，请入库后再操作");
        }
        if (isTrue) {
            cutOrdersDocument.setProductStatus(4);

            //当该计划单对应的水刺制令单全为完成或者关结时修改
            String productionPlanNumber = cutOrdersDocument.getProductionPlanSheet();
            //通过计划单号，判断是否是合并单
            String[] split = productionPlanNumber.split(",");

            //定义所有水刺制令单完成或者关结的标志
            boolean flag = true;


            for (String planNumber : split) {
                //查出计划单对应的所有水刺制令单
                List<SpunlaceOrder> spunlaceOrderList = spunlaceOrderMapper.selectList(new QueryWrapper<SpunlaceOrder>().lambda().eq(SpunlaceOrder::getProductionPlanNumber, planNumber));

                for (SpunlaceOrder order : spunlaceOrderList) {
                    //如果不为已完成或者已关结修改标志为false
                    if (!"8".equals(order.getDocumentStatus()) && !"9".equals(order.getDocumentStatus())) {
                        flag = false;
                        break;
                    }
                }

                //查出计划单对应的所有分切制令单
                List<CutOrdersDocument> cutOrdersDocumentList = spunlaceOrderMapper.getFqInfo(planNumber);

                if (flag) {

                    for (CutOrdersDocument cutOrdersDocument1 : cutOrdersDocumentList) {
                        if (!cutOrdersDocument1.getSplittingOrderNumber().equals(cutOrdersDocument.getSplittingOrderNumber()) &&4 != cutOrdersDocument1.getProductStatus() && 5 != cutOrdersDocument1.getProductStatus()) {
                            flag = false;
                            break;
                        }
                    }
                }
            }

            if (flag) {
                BackWeight backWeight = new BackWeight();
                backWeight.setPlanCode(productionPlanNumber);
                //修改排程单和排程计划单状态为已完成
                schedulingPlanFeignService.updatePlanFinishStatus(backWeight);
            }

            return updateById(cutOrdersDocument);
        } else {
            throw new GlobalException("存在未分切母卷");
        }
    }

    /**
     * 关结
     *
     * @param closeVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean close(CloseVo closeVo) {
        //仅暂停的制令单可以进行关结操作
        CutOrdersDocument cutOrdersDocument = getById(closeVo.getId());
        if (cutOrdersDocument.getProductStatus() != 3) {
            throw new GlobalException("仅暂停的制令单可以进行关结操作");
        }
        //校验制令单内是否存在“未分切”的产品号码，如存在不允许单据完成，提醒：存在未分切母卷
        boolean isTrue = true;
        List<CutOrdersDocumentDetail> cutOrdersDocumentDetailList = cutOrdersDocumentDetailMapper.selectList(new QueryWrapper<CutOrdersDocumentDetail>().lambda().eq(CutOrdersDocumentDetail::getDocumentNum, cutOrdersDocument.getSplittingOrderNumber()));
        for (CutOrdersDocumentDetail entityDetail : cutOrdersDocumentDetailList) {
            if (entityDetail.getSlittingStatus() == 1) {
                isTrue = false;
                break;
            }
        }
        //操作时校验小卷打包页面是否存在此分切执行单的小卷，是则提示“存在小卷未打包，请打包后再操作”，否则操作成功
        List<RollPacking> rollPackings = rollPackingMapper.selectList(new QueryWrapper<RollPacking>().lambda().eq(RollPacking::getSplittingOrderNumber, cutOrdersDocument.getSplittingOrderNumber()));
        if (rollPackings.size() > 0) {
            throw new GlobalException("存在小卷未打包，请打包后再操作");
        }
        //操作时校验成品称重页面是否存在此分切执行单的成品未入库，是则提示“存在小卷未打包，请打包后再操作”，否则操作成功
        List<WeighingFinishedMaterialProduct> weighingFinishedMaterialProducts = weighingFinishedMaterialProductMapper.selectList(new QueryWrapper<WeighingFinishedMaterialProduct>().lambda().eq(WeighingFinishedMaterialProduct::getSplittingOrderNumber, cutOrdersDocument.getSplittingOrderNumber()));
        boolean isWeightAll = true;
        for (WeighingFinishedMaterialProduct entity : weighingFinishedMaterialProducts) {
            if (entity.getStorageStatus() == 1) {
                isWeightAll = false;
                break;
            }
        }
        if (!isWeightAll) {
            throw new GlobalException("存在未入库数据，请入库后再操作");
        }
        if (isTrue) {
            cutOrdersDocument.setCloseBy(SecurityUtils.getUsername())
                    .setCloseReason(closeVo.getCloseReason())
                    .setCloseTime(new Date())
                    .setProductStatus(5);

            //当该计划单对应的水刺制令单全为完成或者关结时修改
            String productionPlanNumber = cutOrdersDocument.getProductionPlanSheet();
            //通过计划单号，判断是否是合并单
            String[] split = productionPlanNumber.split(",");

            //定义所有水刺制令单完成或者关结的标志
            boolean flag = true;


            for (String planNumber : split) {
                //查出计划单对应的所有水刺制令单
                List<SpunlaceOrder> spunlaceOrderList = spunlaceOrderMapper.selectList(new QueryWrapper<SpunlaceOrder>().lambda().eq(SpunlaceOrder::getProductionPlanNumber, planNumber));

                for (SpunlaceOrder order : spunlaceOrderList) {
                    //如果不为已完成或者已关结修改标志为false
                    if (!"8".equals(order.getDocumentStatus()) && !"9".equals(order.getDocumentStatus())) {
                        flag = false;
                        break;
                    }
                }

                //查出计划单对应的所有分切制令单
                List<CutOrdersDocument> cutOrdersDocumentList = spunlaceOrderMapper.getFqInfo(planNumber);

                if (flag) {

                    for (CutOrdersDocument cutOrdersDocument1 : cutOrdersDocumentList) {
                        if (!cutOrdersDocument1.getSplittingOrderNumber().equals(cutOrdersDocument.getSplittingOrderNumber()) &&4 != cutOrdersDocument1.getProductStatus() && 5 != cutOrdersDocument1.getProductStatus()) {
                            flag = false;
                            break;
                        }
                    }
                }
            }


            if (flag) {
                BackWeight backWeight = new BackWeight();
                backWeight.setPlanCode(productionPlanNumber);
                //修改排程单和排程计划单状态为已完成
                schedulingPlanFeignService.updatePlanFinishStatus(backWeight);
            }

            return updateById(cutOrdersDocument);
        } else {
            throw new GlobalException("存在未分切母卷");
        }


    }

    /**
     * 查询水刺及分切数据
     *
     * @param selectCombinationListVo
     * @return
     */
    @Override
    public List<SelectCombinationListDto> selectCombinationList(SelectCombinationListVo selectCombinationListVo) {

        List<SelectCombinationListDto> result = new ArrayList<>();
        //查询分切数据
        List<SelectCombinationListDto> data = cutOrdersDocumentMapper.getData(selectCombinationListVo);
        //查询水刺数据
        List<SelectCombinationListDto> data1 = spunlaceOrderMapper.getData(selectCombinationListVo);
        result.addAll(data);
        result.addAll(data1);
        return result;
    }

    /**
     * 废料打印
     *
     * @param wasteTubeVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean wastePrint(WasteTubeVo wasteTubeVo) throws Exception {

        WasteTube wasteTube = new WasteTube();
        String authorityCoding = feignService.getAuthorityCoding("productionTube:prostatistics:wastemanage:list");
        if (authorityCoding == null) {
            throw new GlobalException("未进行单据配置,单据编码生成失败");
        }
        wasteTube.setWasteScrapNumber(authorityCoding);
        wasteTube.setFeedOrderNumber(wasteTubeVo.getFeedOrderNumber());
        wasteTube.setWasteCode(wasteTubeVo.getWasteCode());
        wasteTube.setGrossWeight(wasteTubeVo.getGrossWeight());
        wasteTube.setTareWeight(wasteTubeVo.getTareWeight());
        wasteTube.setNetWeight(wasteTubeVo.getNetWeight());
        wasteTube.setLineCode(wasteTubeVo.getLineCode());
        wasteTube.setPrinterBy(SecurityUtils.getUsername());
        wasteTube.setPrinterTime(new Date());
        wasteTube.setWasteName(wasteTubeVo.getWasteName());
        wasteTube.setWasteSpec(wasteTubeVo.getWasteSpec());
        wasteTube.setWasteType(3);
        return wasteTubeService.insertWasteTube(wasteTube) > 0;
    }

    /**
     * 手持pda 投料列表
     *
     * @param cutFeedVo
     * @return
     */
    @Override
    public List<CutFeedDto> cutFeedList(CutFeedVo cutFeedVo) {

        Long deptId = SecurityUtils.getDeptId();
        cutFeedVo.setDeptId(deptId);
        if (cutFeedVo.getNumber() == 3) {
            //分切列表
            return cutOrdersDocumentMapper.getCutFeedList(cutFeedVo);
        } else if (cutFeedVo.getNumber() == 2) {
            //水刺列表
            return spunlaceOrderMapper.getSpunlaceOrderListPda(cutFeedVo);
        } else if (cutFeedVo.getNumber() == 1) {
            //脱脂列表
            return degreasDocumentMapper.getDegreasDocumentListPda(cutFeedVo);
        } else {
            return new ArrayList<>();
        }

    }

    /**
     * 手持pda 投料详情
     *
     * @param number
     * @param id
     * @return
     */
    @Override
    public CutFeedDto cutFeedView(int number, Long id) {
        CutFeedDto cutFeedDto = new CutFeedDto();
        //分切类型
        List<SysDictData> typeArray = DictUtils.getDictCache("android_pda_feed_type");
        Map<String, String> typeMap = typeArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //分切详情
        if (number == 3) {
            CutOrdersDocumentDto viewById = cutOrdersDocumentMapper.getViewById(id);
            cutFeedDto.setId(viewById.getId());
            cutFeedDto.setOrderNumber(viewById.getSplittingOrderNumber());
            cutFeedDto.setCutFeedDict(typeMap.get(String.valueOf(number)));
        }
        return cutFeedDto;
    }

    /**
     * 通过id线别名称及编码
     *
     * @param id
     * @return
     */
    @Override
    public List<GetDataLineTypeNameDto> getDataLineTypeName(Long id) {
        CutOrdersDocument cutOrdersDocument = getById(id);
        List<String> lineCode = Arrays.asList(cutOrdersDocument.getLineTypeName().split(","));
        //获取车间建模列表
        List<SysShopModeling> list = sysShopModelingService.list();
        List<GetDataLineTypeNameDto> resultList = new ArrayList<>();
        for (SysShopModeling entity : list) {
            for (String entity2 : lineCode) {
                if (entity.getModelingCode().equals(entity2)) {
                    GetDataLineTypeNameDto getDataLineTypeNameDto = new GetDataLineTypeNameDto();
                    getDataLineTypeNameDto.setLineCode(entity.getModelingCode());
                    getDataLineTypeNameDto.setLineName(entity.getModelingName());
                    resultList.add(getDataLineTypeNameDto);
                }
            }
        }
        return resultList;
    }


    /**
     * 通过阶别，线别编码查询生产中的制令单号
     *
     * @param getOrderNumVo
     * @return
     */
    @Override
    public List<OrderNumDto> getOrderNum(GetOrderNumVo getOrderNumVo) {
        List<OrderNumDto> resultList = new ArrayList<>();
        if (getOrderNumVo.getRank() == 2) {
            //查询水刺制令单
            SpunlaceOrderVo spunlaceOrderVo = new SpunlaceOrderVo();
            spunlaceOrderVo.setProductionLine(getOrderNumVo.getLineCode());
            spunlaceOrderVo.setDocumentStatus("1");
            List<SpunlaceOrderDto> spunlaceOrderList = spunlaceOrderMapper.getSpunlaceOrderNumList(spunlaceOrderVo);
            for (SpunlaceOrderDto entity : spunlaceOrderList) {
                OrderNumDto orderNumDto = new OrderNumDto();
                orderNumDto.setOrderNo(entity.getSpunlaceOrderNumber());
                orderNumDto.setMaterialName(entity.getMaterialName());
                orderNumDto.setMaterialCode(entity.getMaterialCode());
                orderNumDto.setLineCode(entity.getProductionLine());
                orderNumDto.setMaterialSpec(entity.getMaterialSpec());
                resultList.add(orderNumDto);
            }
            return resultList;
        } else if (getOrderNumVo.getRank() == 3) {
            //查询分切制令单
            CutOrdersDocumentVo cutOrdersDocumentVo = new CutOrdersDocumentVo();
            cutOrdersDocumentVo.setLineTypeName(getOrderNumVo.getLineCode());
            cutOrdersDocumentVo.setProductStatus(1);
            List<CutOrdersDocumentDto> list = cutOrdersDocumentMapper.getCutOrdersDocumentList(cutOrdersDocumentVo);
            for (CutOrdersDocumentDto entity : list) {
                OrderNumDto orderNumDto = new OrderNumDto();
                orderNumDto.setOrderNo(entity.getSplittingOrderNumber());
                orderNumDto.setMaterialCode(entity.getMaterialCode());
                orderNumDto.setMaterialName(entity.getMaterialName());
                orderNumDto.setLineCode(entity.getLineTypeName());
                orderNumDto.setMaterialSpec(entity.getMaterialSpec());
                resultList.add(orderNumDto);
            }
            return resultList;
        } else if (getOrderNumVo.getRank() == 1) {
            //查询脱脂制令单
            DegreasDocumentVo degreasDocumentVo = new DegreasDocumentVo();
            degreasDocumentVo.setLineCode(getOrderNumVo.getLineCode());
            degreasDocumentVo.setStatus(2);
            List<DegreasDocumentDto> outDegresDocument = degreasDocumentMapper.getOutDegresDocument(degreasDocumentVo);
            for (DegreasDocumentDto entity : outDegresDocument) {
                OrderNumDto orderNumDto = new OrderNumDto();
                orderNumDto.setOrderNo(entity.getDegreasOrderNumber());
                orderNumDto.setMaterialCode(entity.getMaterialCode());
                orderNumDto.setMaterialName(entity.getMaterialName());
                orderNumDto.setLineCode(entity.getLineCode());
                orderNumDto.setMaterialSpec(entity.getMaterialSpec());
                resultList.add(orderNumDto);
            }
            return resultList;
        } else {
            return resultList;
        }
    }

    /**
     * 分切制令单pda产出列表
     *
     * @param pdaVo
     * @return
     */
    @Override
    public List<PdaDto> pdaList(PdaVo pdaVo) {

        return cutOrdersDocumentMapper.getPdaList(pdaVo);
    }

}
